
#include <QtGui>
#include <QLabel>
#include <QTabWidget>
#include <QTextEdit>
#include <QGraphicsScene>
#include <QButtonGroup>
#include <QSpacerItem>


#include "mainwindow.h"
#include "scene.h"


const int InsertTextButton = 10;


MainWindow::MainWindow()
{
	SBMLText = new QTextEdit;
	MIMMLText = new QTextEdit;
	createActions();
	createMenus();
	createToolBar();
	createToolBox();

	scene = new Scene();
	scene->setSceneRect(QRect(QPoint(0,0),QPoint(2000,2000)));
	scene->setMode(Scene::Move);
	scene->grid = false;
	
	connect(scene, SIGNAL(itemInserted(DiagramItem *)),
        this, SLOT(itemInserted(DiagramItem *)));
         connect(scene, SIGNAL(EdgeInserted(Edge *)),
         this, SLOT(EdgeInserted(Edge *)));

	view = new QGraphicsView(scene);
	//view->setDragMode(QGraphicsView::RubberBandDrag);  // context menu dissapears. http://bugreports.qt.nokia.com/browse/QTBUG-10138
   	view->setRenderHints(QPainter::Antialiasing
                         | QPainter::TextAntialiasing);
	view->setContextMenuPolicy(Qt::ActionsContextMenu);
	view->viewport()->setMouseTracking(true);
	
    connect(scene, SIGNAL(selectionChanged()),
            this, SLOT(updateActions()));

	tab = new QTabWidget;
	tab -> addTab(view, "&MIM");
	SBMLText->setFrameRect(QRect(0,0,5000,5000));
        SBMLText->setReadOnly(true);
	tab->addTab(SBMLText, "&SBML");
	
	MIMMLText->setFrameRect(QRect(0,0,5000,5000));
        MIMMLText->setReadOnly(true);
	tab->addTab(MIMMLText, "&MIMML");
	
    connect(tab, SIGNAL(currentChanged(int)),
            this, SLOT(updateActions()));

	connect(SBMLText->document(), SIGNAL(contentsChanged()),
             this, SLOT(documentWasModified()));
    connect(MIMMLText->document(), SIGNAL(contentsChanged()),
             this, SLOT(documentWasModified()));
	
	
 	QHBoxLayout *layout = new QHBoxLayout;
	layout->addWidget(toolBox);
	layout->addWidget(tab);

	QWidget *widget = new QWidget;
	widget->setLayout(layout);


	setCentralWidget(widget);
	setWindowTitle(tr("MIMTool"));
    setWindowIcon(QIcon(":/images/mimIcon.png"));

	updateActions();

}

void MainWindow::buttonGroupClicked(int id)
 {
     QList<QAbstractButton *> buttons = buttonGroup->buttons();
     foreach (QAbstractButton *button, buttons) 
	{
     		if (buttonGroup->button(id) != button)
         		{button->setChecked(false);}
	}
	if (id < 6 )
	{ 
		if ( scene->myMode == Scene::Insert)
		{
			buttonGroup->button(id)->setChecked(false);
			scene->setMode(Scene::Move);
		} else {
                        scene->updatePoints(true);
			scene->setMode(Scene::Insert); 
			scene->setItemType(DiagramItem::DiagramType(id));
		}
	}
	else if ( id < 15)
    { 
		if ( scene->myMode == Scene::InsertEdge)
		{
			buttonGroup->button(id)->setChecked(false);
			scene->setMode(Scene::Move);
			scene->updatePoints(true);
		} else {
			QList<QGraphicsItem *> Items = scene->selectedItems();
			if (Items.size() == 2 && Items.first()->type() == DiagramItem::Type && Items.at(1)->type() == DiagramItem::Type)
			{
				scene->setArrowType(Edge::EdgeType(id - 6));
				scene->drawSemiAuto(Items);	
			}
			else
			{
				scene->setMode(Scene::InsertEdge);
				scene->setArrowType(Edge::EdgeType(id - 6));
			}
		}
	}
	else if ( id > 14)
	{
		if ( scene->myMode == Scene::InsertConEdge)
		{
			buttonGroup->button(id)->setChecked(false);
			scene->setMode(Scene::Move);
			scene->updatePoints(true);
		} else {
			scene->setMode(Scene::InsertConEdge);
			scene->setArrowType(Edge::EdgeType(id - 6));
		}
	}

 }
void MainWindow::newFile()
 {
     if (maybeSave(0)) {
		SBMLText->clear();
		MIMMLText->clear();
        setCurrentFile("");
		mainFile.setFile("");
		setWindowTitle(tr("MIMTool"));
     }
 } 
void MainWindow::open()
 {
         QString fileName = QFileDialog::getOpenFileName(this , tr("Open"), "",  tr("XML file (*.xml)"));
		 maybeSave(1);
		 mainFile.setFile(fileName);
         if (!fileName.isEmpty())
         {
	  	 	SBMLText->clear();
			MIMMLText->clear();
			scene->diagramItems.clear();
			scene->edges.clear();
			scene->ids.clear();
			scene->clear();
            loadFile(fileName, 0);
            loadFile(fileName, 2);
        }
	    
     
 }
bool MainWindow::save()
 {
     if (curFile.isEmpty()) {
         return saveAs();
     } else {
         return saveFile(curFile);
     }
 }
bool MainWindow::saveAs()
 {
     QString fileName = QFileDialog::getSaveFileName(this , tr("Save As"), "untitled",  tr("XML file (*.xml)"));
     if (fileName.isEmpty())
         return false;

     return saveFile(fileName);
 }
void MainWindow::loadFile(const QString &fileName, const int &index)
 {
     QFile file(fileName);
	 QFile file2(fileName);
     if (!file.open(QFile::ReadOnly | QFile::Text)) {
         QMessageBox::warning(this, tr("Application"),
                              tr("Cannot read file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
         return;
     }
     if (!file2.open(QFile::ReadOnly | QFile::Text)) {
         QMessageBox::warning(this, tr("Application"),
                              tr("Cannot read file %1:\n%2.")
                              .arg(fileName)
                              .arg(file2.errorString()));
	 
         return;
	 }
  
     QTextStream in(&file);
     QApplication::setOverrideCursor(Qt::WaitCursor);
         if ( index == 2)
                MIMMLText->setPlainText(in.readAll());
         else if ( index == 0)
         {
			scene->loadFromXml(&file) ;      
			scene->loadFromXmlInteraction(&file2);
			QString sbml = scene->saveToSBML2();
			SBMLText->setPlainText(sbml);
         }
     QApplication::restoreOverrideCursor();

     setCurrentFile(fileName);
	 mainFile.setFile(fileName);
     statusBar()->showMessage(tr("File loaded"), 2000);
	 setWindowTitle( mainFile.baseName() + " - MIMTool");
}
void MainWindow::about()
 {
    QMessageBox::about(this, tr("About MIM Drawing Tool"),
             tr("The <b>MIM Drawing Tool</b> is for drawing  "
                "Molecular Interaction Maps. They can be drawn " 
                " manually and semi-automatically."));
 }

void MainWindow::deleteItem()
 {
	foreach (QGraphicsItem *item1, scene->selectedItems())
		deleteFunc(item1);	

	update();
 }
bool MainWindow::maybeSave(const int &index)
 {
	 if ( !curFile.isEmpty() || (curFile.isEmpty() && !scene->items().isEmpty()))
	 {
         QMessageBox::StandardButton ret;
         ret = QMessageBox::warning(this, tr("MIMTool"),
                      tr("Do you want to save your changes?"),
                      QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
         if (ret == QMessageBox::Yes)
		 {
            if (!save())
				return false;
 	 		SBMLText->clear();
			MIMMLText->clear();
			scene->diagramItems.clear();
			setCurrentFile("");
			mainFile.setFile("");
			setWindowTitle(tr("MIMTool"));
			scene->edges.clear();
			scene->ids.clear();
			scene->clear();
			return true;
			}
		 else if (ret == QMessageBox::Cancel)
             return false;
		 else if (ret == QMessageBox::No)
		 {
			 if ( index == 0 )
			 {
	 		SBMLText->clear();
			MIMMLText->clear();
			scene->diagramItems.clear();
			scene->edges.clear();
			scene->ids.clear();
			scene->clear();
             return true;
			 } else
				 return true;
		 }
     return true;
	 }
	 else
		 return true;
 }
bool MainWindow::saveFile(const QString &fileName)
 {
     QFile file(fileName);
     if (!file.open(QFile::WriteOnly | QFile::Text)) {
         QMessageBox::warning(this, tr("Application"),
                              tr("Cannot write file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
         return false;
     }

     QTextStream out(&file);
     QApplication::setOverrideCursor(Qt::WaitCursor);
	 /*if ( tab->currentIndex() == 1)
		out << SBMLText->toPlainText();
	 else if ( tab->currentIndex() == 2)
		out << MIMMLText->toPlainText();
	 else if ( tab->currentIndex() == 0 )*/
		 out << scene->saveToXML();
     
     QApplication::restoreOverrideCursor();

     setCurrentFile(fileName);
	 mainFile.setFile(fileName);
     statusBar()->showMessage(tr("File saved"), 2000);
	 setWindowTitle( mainFile.baseName() + " - MIMTool");
     return true;
 }

void MainWindow::deleteFunc(QGraphicsItem *item1)
  {
		if ( item1->type() == DiagramItem::Type )
		{
			DiagramItem *item = qgraphicsitem_cast<DiagramItem *>(item1);	

			if ( item->diagramType() == 7)
				item->host->intrans = false;
			if ( item->diagramType() == 6)
				item->host->isComplex = false;
			if ( item->filtered )
				scene->unfiltering();

			foreach(Edge *edge2, item->edges)
			{	
				deleteFunc(edge2);
			}
			scene->ids.removeOne(item->myId);
			scene->removeItem(item1);
            scene->diagramItems.removeOne(item);

		} else if (item1->type() == Edge::Type )
		{
			Edge *item = qgraphicsitem_cast<Edge *>(item1);
			if ( item->isComplex )
			{
				deleteFunc(item->complex);
				scene->diagramItems.removeOne(item->complex);
			}
			if ( item->intrans )
			{
				scene->ids.removeOne(item->myId);
				scene->removeItem(item->trans);
				scene->diagramItems.removeOne(item->trans);
			}
			if ( item->startItem()->diagramType() == 8 )
			{
				item->startItem()->host->invisibleItems.removeOne(item->startItem());
				scene->ids.removeOne(item->myId);
				scene->removeItem(item->startItem());
				scene->diagramItems.removeOne(item->startItem());
			}
			if ( item->endItem()->diagramType() == 8 )
			{
				item->endItem()->host->invisibleItems.removeOne(item->endItem());
				scene->ids.removeOne(item->myId);
				scene->removeItem(item->endItem());
				scene->diagramItems.removeOne(item->endItem());
			}
			if ( item->edgeType() > 9 )
			{
				item->endItem()->host->conEdges.removeOne(item);
			}

			foreach(Edge *edge, item->conEdges)
				deleteFunc(edge);
			foreach(DiagramItem *item3, item->invisibleItems)
				deleteFunc(item3);
			scene->ids.removeOne(item->myId);
			scene->removeItem(item);
            scene->edges.removeOne(item);
		} else
		{
			scene->removeItem(item1);
        }
		
  }
void MainWindow::updateActions()
 {
	QList<QGraphicsItem *> Items = scene->selectedItems();
    bool hasSelection = !(scene->selectedItems().isEmpty());

	if (tab->currentIndex() == 1 || tab->currentIndex() == 2)
	{
		deleteAction->setEnabled(false);
		propertiesAction->setEnabled(false);
		reverseAction->setEnabled(false);
		newAction->setEnabled(false);
		openAction->setEnabled(false);
		saveAction->setEnabled(false);
		importAction->setEnabled(false);
		exportAction->setEnabled(false);
		inTransAction->setEnabled(false);
		printAction->setEnabled(false);
		printPNGAction->setEnabled(false);
		gridAction->setEnabled(false);
		numberingAction->setEnabled(false);
		filteringAction->setEnabled(false);
		unfilteringAction->setEnabled(false);
		bringToFrontAction->setEnabled(false);
		sendToBackAction->setEnabled(false);
		branchRightAction->setEnabled(false);
		branchLeftAction->setEnabled(false);
		selectAllAction->setEnabled(false);

	} else
	{

		deleteAction->setEnabled(hasSelection);
		propertiesAction->setEnabled(false);
		reverseAction->setEnabled(false);
		newAction->setEnabled(true);
		openAction->setEnabled(true);
		saveAction->setEnabled(true);
		importAction->setEnabled(false);
		exportAction->setEnabled(false);
		inTransAction->setEnabled(false);
		printAction->setEnabled(true);
		printPNGAction->setEnabled(true);
		gridAction->setEnabled(true);
		numberingAction->setEnabled(true);
		filteringAction->setEnabled(false);
		unfilteringAction->setEnabled(false);
		bringToFrontAction->setEnabled(false);
		sendToBackAction->setEnabled(false);
		branchRightAction->setEnabled(false);
		branchLeftAction->setEnabled(false);
		selectAllAction->setEnabled(true);


		if ( hasSelection && Items.first()->type() == Edge::Type && Items.size() == 1 )
		{
			Edge *item = qgraphicsitem_cast<Edge *>(Items.first());
			propertiesAction->setEnabled(true);
			if (!item->intrans)
				inTransAction->setEnabled(true);
			bringToFrontAction->setEnabled(true);
			sendToBackAction->setEnabled(true);
			if ( item->edgeType() < 9 )
				reverseAction->setEnabled(true);
			if ( item->startItem()->diagramType() == 8 && item->branchRight == false  )
				branchRightAction->setEnabled(true);
			if ( item->startItem()->diagramType() == 8 && item->branchLeft == false  )
				branchLeftAction->setEnabled(true);
			

		}

		if ( hasSelection && Items.first()->type() == DiagramItem::Type && Items.size() == 1 )
		{
			
			DiagramItem *item = qgraphicsitem_cast<DiagramItem *>(Items.first());
			if ( item->filtered == true )
				unfilteringAction->setEnabled(true);
			else
				filteringAction->setEnabled(true);

            if (item->diagramType() < 4 )
				propertiesAction->setEnabled(true);
			
		}

		 foreach (QAction *action, view->actions())
			view->removeAction(action);

			foreach (QAction *action, editMenu->actions()) 
			{
				if (action->isEnabled())
					view->addAction(action);
			}	
	}

}


void MainWindow::setCurrentFile(const QString &fileName)
 {
     curFile = fileName;
	 mainFile.setFile(fileName);
     SBMLText->document()->setModified(false);
     setWindowModified(false);
 }
QString MainWindow::strippedName(const QString &fullFileName)
 {
     return QFileInfo(fullFileName).fileName();
 }

void MainWindow::inTrans()
{
	QList<QGraphicsItem *> Items = scene->selectedItems();
	Edge *arrow = qgraphicsitem_cast<Edge *>(Items.first());
	DiagramItem *transItem = new DiagramItem(DiagramItem::DiagramType(7));;
	arrow->intrans = true;
	transItem->host = arrow;
	arrow->trans = transItem;
	transItem->setPen(QPen(Qt::black, 6));
	transItem->setPos(QPointF(arrow->path().pointAtPercent(0.5)));
	transItem->setZValue(100.0);
	scene->addItem(transItem);
	scene->ids.append(transItem->myId);
	scene->diagramItems.append(transItem);
	update();

}

void MainWindow::createActions()
{
	newAction = new QAction(tr("&New"), this);
	newAction->setIcon(QIcon(":/images/new.png"));
	newAction->setShortcut(tr("Ctrl+N"));
	connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));

	openAction = new QAction(tr("&Open"), this);
	openAction->setIcon(QIcon(":/images/open.png"));
	openAction->setShortcut(tr("Ctrl+O"));
	connect(openAction, SIGNAL(triggered()), this, SLOT(open()));

	saveAction = new QAction(tr("&Save"), this);
	saveAction->setIcon(QIcon(":/images/save.png"));
	saveAction->setShortcut(tr("Ctrl+S"));
	connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));

	saveAsAction = new QAction(tr("&Save As"), this);
	connect(saveAsAction, SIGNAL(triggered()), this, SLOT(saveAs()));

	importAction = new QAction(tr("I&mport"), this);
	importAction->setShortcut(tr("Ctrl+M"));

	exportAction = new QAction(tr("&Export"), this);
	exportAction->setShortcut(tr("Ctrl+E"));

	exitAction = new QAction(tr("&Exit"),this);
	connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));

	aboutAction = new QAction(tr("About &MIM"), this);
	aboutAction->setStatusTip(tr("Show the application's About box"));
    connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));

	//helpAction = new QAction(tr("&Help"), this);

	deleteAction = new QAction(tr("&Delete"), this);
	deleteAction->setIcon(QIcon(":/images/delete.png"));
	deleteAction->setShortcut(tr("Del"));
	connect(deleteAction, SIGNAL(triggered()), this, SLOT(deleteItem()));

	propertiesAction = new QAction(tr("&Properties.."), this);	
	connect(propertiesAction, SIGNAL(triggered()), this, SLOT(properties()));

	/*deleteAllAction = new QAction(tr("Delete All"), this);
	deleteAllAction->setIcon(QIcon(":/images/deleteAll.png"));
	connect(deleteAllAction, SIGNAL(triggered()), this, SLOT(deleteAllItems()));*/

	inTransAction = new QAction(tr("Add Intermolecular Glyph"),this);
	connect(inTransAction, SIGNAL(triggered()), this, SLOT(inTrans()));

	printAction = new QAction(tr("Save as PDF image"),this);
	printAction->setIcon(QIcon(":/images/pdf.png"));
	connect(printAction, SIGNAL(triggered()), this, SLOT(print()));

	printPNGAction = new QAction(tr("Save as PNG image"),this);
	printPNGAction->setIcon(QIcon(":/images/pngSave.png"));
	connect(printPNGAction, SIGNAL(triggered()), this, SLOT(printPNG()));

	gridAction = new QAction(tr("&Grid"), this);
	gridAction->setIcon(QIcon(":/images/grid.png"));
	connect(gridAction, SIGNAL(triggered()), this, SLOT(grid()));

	numberingAction = new QAction(tr("&Add text"), this);
	numberingAction->setIcon(QIcon(":/images/T.png"));
	connect(numberingAction, SIGNAL(triggered()), this, SLOT(numbering()));

	filteringAction = new QAction(tr("&Filter the interactions"), this);
	connect(filteringAction, SIGNAL(triggered()), this, SLOT(filtering()));

	unfilteringAction = new QAction(tr("&Unfilter the interactions"), this);
	connect(unfilteringAction, SIGNAL(triggered()), this, SLOT(unfiltering()));

	reverseAction = new QAction(tr("&Reverse the interaction direction"), this);
	connect(reverseAction, SIGNAL(triggered()), this, SLOT(reverse())); 

	bringToFrontAction = new QAction(tr("Bring to front"),this);
	connect(bringToFrontAction, SIGNAL(triggered()), this, SLOT(bringToFront()));

	sendToBackAction = new QAction(tr("Send to back"),this);
	connect(sendToBackAction, SIGNAL(triggered()), this, SLOT(sendToBack()));

	sbmlAction = new QAction(tr("Save as SBML document"),this);
	connect(sbmlAction, SIGNAL(triggered()), this, SLOT(saveSBML()));

	//autoLayoutAction = new QAction(tr("Generate automatic layout"),this);
	//connect(autoLayoutAction, SIGNAL(triggered()), this, SLOT(generateAutoLayout()));

	branchRightAction = new QAction(tr("Add right branching"),this);
	connect(branchRightAction, SIGNAL(triggered()), this, SLOT(addRightBranching()));

	branchLeftAction = new QAction(tr("Add left branching"),this);
	connect(branchLeftAction, SIGNAL(triggered()), this, SLOT(addLeftBranching()));

	selectAllAction = new QAction(tr("SelectAll"),this);
	selectAllAction->setShortcut(tr("Ctrl+A"));
	connect(selectAllAction, SIGNAL(triggered()), this, SLOT(selectAll()));



}
void MainWindow::createMenus()
{
	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(newAction);
	fileMenu->addAction(openAction);
	fileMenu->addAction(saveAction);
	fileMenu->addAction(saveAsAction);
	fileMenu->addAction(sbmlAction);
	fileMenu->addSeparator();
	fileMenu->addAction(importAction);
	fileMenu->addAction(exportAction);
	//fileMenu->addAction(autoLayoutAction);
	fileMenu->addSeparator();
	fileMenu->addAction(exitAction);
	
	editMenu = menuBar()->addMenu(tr("&Edit"));
	editMenu->addAction(deleteAction);
	editMenu->addSeparator();
	editMenu->addAction(selectAllAction);
	editMenu->addSeparator();
	editMenu->addAction(propertiesAction);
	editMenu->addSeparator();
	editMenu->addAction(inTransAction);
	editMenu->addAction(reverseAction);
	editMenu->addAction(filteringAction);
	editMenu->addAction(unfilteringAction);
	editMenu->addAction(bringToFrontAction);
	editMenu->addAction(sendToBackAction);
	editMenu->addAction(branchRightAction);
	editMenu->addAction(branchLeftAction);
	
	helpMenu = menuBar()->addMenu(tr("&Help"));
	//helpMenu->addAction(helpAction);
	helpMenu->addAction(aboutAction);
}


void MainWindow::createToolBar()
{
	fileToolBar = addToolBar(tr("&File"));
	fileToolBar->addAction(newAction);
	fileToolBar->addAction(openAction);
	fileToolBar->addAction(saveAction);
	fileToolBar->addAction(printAction);
	fileToolBar->addAction(printPNGAction);

	 sceneScaleCombo = new QComboBox;
     QStringList scales;
     scales << tr("50%") << tr("75%") << tr("100%") << tr("125%") << tr("150%");
     sceneScaleCombo->addItems(scales);
     sceneScaleCombo->setCurrentIndex(2);
     connect(sceneScaleCombo, SIGNAL(currentIndexChanged(const QString &)),
             this, SLOT(sceneScaleChanged(const QString &)));

	editToolBar = addToolBar(tr("&Edit"));
	editToolBar->addAction(deleteAction);
	//editToolBar->addAction(deleteAllAction);
	editToolBar->addAction(numberingAction);

	viewToolbar = addToolBar(tr("&View"));
	viewToolbar->addWidget(sceneScaleCombo);
	viewToolbar->addAction(gridAction);

}

void MainWindow::createToolBox()
 {
	buttonGroup = new QButtonGroup;
	buttonGroup->setExclusive(false);
     connect(buttonGroup, SIGNAL(buttonClicked(int)),
             this, SLOT(buttonGroupClicked(int)));

	QVBoxLayout *layoutN = new QVBoxLayout;
	layoutN->addWidget(createCellWidget(tr(""),
		DiagramItem::protein));
	layoutN->addWidget(createCellWidget(tr(""),
		DiagramItem::domain));
	layoutN->addWidget(createCellWidget(tr(""),
		DiagramItem::DNA));
	layoutN->addWidget(createCellWidget(tr(""),
		DiagramItem::Small));
	layoutN->addWidget(createCellWidget(tr(""),
		DiagramItem::sourceSink));
	layoutN->addWidget(createCellWidget(tr(""),
		DiagramItem::Dot));
	space1 = new QSpacerItem(16, 16, QSizePolicy::Minimum, QSizePolicy::Expanding);
	layoutN->addSpacerItem(space1);
	
	

	QVBoxLayout *layoutR = new QVBoxLayout;
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::nonCovalent));
 	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::covalentMo));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::covalentBond));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::stoichiometric));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::lossReactant));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::transcription));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::combination));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::firstFeature));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::nextFeature));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::cleavage));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::stimulation));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::requirement));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::inhibition));
	layoutR->addWidget(createCellWidget(tr(""),
                       Edge::catalysis));
	space3 = new QSpacerItem(16, 16, QSizePolicy::Minimum, QSizePolicy::Expanding);
	layoutR->addSpacerItem(space3);

     QWidget *nodeWidget = new QWidget;
     nodeWidget->setLayout(layoutN);

     QWidget *reactionWidget = new QWidget;
     reactionWidget->setLayout(layoutR);


     toolBox = new QToolBox;
     toolBox->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored));
     toolBox->setMinimumWidth(nodeWidget->sizeHint().width());
	toolBox->addItem(nodeWidget, tr("Entity Glyphs"));
     toolBox->addItem(reactionWidget, tr("Interactions"));
	
 }


 QWidget *MainWindow::createCellWidget(const QString &text,
                       DiagramItem::DiagramType type)
 {
	DiagramItem item(type);
	QToolButton *button = new QToolButton;
	button->setIconSize(QSize(40, 20));
        button->setCheckable(true);
        buttonGroup->addButton(button, int(type));

	switch (type) {
         case DiagramItem::protein:
		button->setIcon(QIcon(":/images/se.png"));
		button->setToolTip("Simple Physical Entity");
             break;
          case DiagramItem::domain:
		button->setIcon(QIcon(":/images/se.png"));
		button->setToolTip("Entity Feature");
             break;
         case DiagramItem::DNA:
		button->setIcon(QIcon(":/images/ce.png"));
		button->setToolTip("Conceptual Entity");
             break;
         case DiagramItem::Small:
		button->setText("modifier");
		button->setToolTip("Modifier");
            break;
         case DiagramItem::sourceSink:
		button->setIcon(QIcon(":/images/ss.png"));
		button->setToolTip("Source/Sink");
             break;
         case DiagramItem::Dot:
		 button->setIcon(QIcon(":/images/rd.png"));
		 button->setToolTip("Restricted Copy Dot Entity");
             break;
        case DiagramItem::Trans:
             break;
        case DiagramItem::Complex:
             break;
     }
	 //button->setFixedWidth(65);
     QGridLayout *layout = new QGridLayout;
     layout->addWidget(button, 0, 0, Qt::AlignHCenter);
     
     QWidget *widget = new QWidget;
     widget->setLayout(layout);

     return widget;
 }
 QWidget *MainWindow::createCellWidget(const QString &text,
                       Edge::EdgeType type)
 {
	QToolButton *button = new QToolButton;
	button->setIconSize(QSize(40, 20));
      button->setCheckable(true);
      buttonGroup->addButton(button, int(type)+6 );

	switch (type) {

         case Edge::nonCovalent:
		button->setIcon(QIcon(":/images/nco.png"));
		button->setToolTip("Non-Covalent Reversible Binding");
             break;
         case Edge::covalentMo:
		button->setIcon(QIcon(":/images/co.png"));
		button->setToolTip("Covalent Modification");
             break;
         case Edge::covalentBond:
		button->setIcon(QIcon(":/images/cob.png"));
		button->setToolTip("Covalent Irreversible Binding");
             break;
         case Edge::stoichiometric:
		button->setIcon(QIcon(":/images/sc.png"));
		button->setToolTip("Stoichiometric Conversion");
             break;
         case Edge::lossReactant:
		button->setIcon(QIcon(":/images/lor.png"));
		button->setToolTip("Production without Loss of Reactants");
             break;
         case Edge::transcription:
		button->setIcon(QIcon(":/images/tr.png"));
		button->setToolTip("Template Reaction");
             break;
         case Edge::combination:
		button->setIcon(QIcon(":/images/com.png"));
		button->setToolTip("State Combination");
             break;
          case Edge::firstFeature:
		button->setIcon(QIcon(":/images/covD.png"));
		button->setToolTip("First Feature Connector");
             break;
          case Edge::nextFeature:
		button->setIcon(QIcon(":/images/com.png"));
		button->setToolTip("Next Feature Connector");
             break;
          case Edge::cleavage:
		button->setIcon(QIcon(":/images/cl.png"));
		button->setToolTip("Covalent Bond Cleavage");
             break;
         case Edge::stimulation :
		button->setIcon(QIcon(":/images/lor.png"));
		button->setToolTip("Stimulation");
             break;
         case Edge::requirement:
		button->setIcon(QIcon(":/images/re.png"));
		button->setToolTip("Necessary Stimulation");
             break;
         case Edge::inhibition:
		button->setIcon(QIcon(":/images/in.png"));
		button->setToolTip("Inhibition");
             break;
         case Edge::catalysis:
		button->setIcon(QIcon(":/images/ec.png"));
		button->setToolTip("Catalysis");
             break;
     }

     QGridLayout *layout = new QGridLayout;
     layout->addWidget(button, 0, 0, Qt::AlignHCenter);
     
     QWidget *widget = new QWidget;
     widget->setLayout(layout);

     return widget;
 }
void MainWindow::itemInserted(DiagramItem *item)
 {
     scene->setMode(Scene::Mode(1));
     buttonGroup->button(int(item->diagramType()))->setChecked(false);

 }
void MainWindow::EdgeInserted(Edge *item)
 {
     scene->setMode(Scene::Mode(1));
     int k = buttonGroup->checkedId();
     buttonGroup->button(int(k))->setChecked(false);
	 scene->clearSelection();
	//scene->update();
	
 }

void MainWindow::properties()
{
    DiagramItem *item = selectedDiagramItem();
    Edge *edge = selectedEdge();

	if (item) {
		PropertiesDiagram2 diagram(item, this);
		diagram.exec();
	} else if (edge) {
        	PropertiesDialog dialog(edge, this);
       		dialog.exec();
    }
}


DiagramItem *MainWindow::selectedDiagramItem() const
{
    QList<QGraphicsItem *> items = scene->selectedItems();
    if (items.count() == 1) {
        return dynamic_cast<DiagramItem *>(items.first());
    } else {
        return 0;
    }
}

Edge *MainWindow::selectedEdge() const
{
    QList<QGraphicsItem *> items = scene->selectedItems();
    if (items.count() == 1) {
        return dynamic_cast<Edge *>(items.first());
    } else {
        return 0;
    }
}

void MainWindow::print()
{
	QList <QGraphicsItem*> items = scene->items();
	if ( items.count() != 0)
	{
		printer= new QPrinter(QPrinter::HighResolution);
		printer->setOutputFormat(QPrinter::PdfFormat);
		printer->setOrientation(QPrinter::Landscape);
		printer->setPaperSize(QPrinter::A3);
		QString fileName = QFileDialog::getSaveFileName(this, tr("Save File As"), "untitled",  tr("Images (*.pdf)"));
		if (!fileName.isEmpty())
		{	
			printer->setOutputFileName(fileName);
			printer->newPage();
			printer->setFontEmbeddingEnabled (false);
			painter = new QPainter(printer);
			QFont f =painter->font();
			f.setPixelSize(10);
			painter->setFont(f);
			QRectF rec = scene->itemsBoundingRect();
			scene->render(painter,printer->pageRect(),rec,Qt::KeepAspectRatio);
			painter->end();
		}	
	}
}
void MainWindow::printPNG()
{
	QImage *image = new QImage(scene->itemsBoundingRect().adjusted(0,10,0,0).size().toSize(), QImage::Format_RGB32);
	image->fill(QColor(Qt::white).rgb());
	QPainter *painter2 = new QPainter(image);
	scene->render(painter2, image->rect(),scene->itemsBoundingRect().adjusted(0,-10,0,10),Qt::KeepAspectRatio);
	QString fileName = QFileDialog::getSaveFileName(this, tr("Save File As"), "untitled",  tr("Images (*.PNG)"));
     if (!fileName.isEmpty())
	 { 
		image->save(fileName);
		painter2->end();
	 }
}

void MainWindow::grid()
{
	if ( scene->grid == false)
		scene->grid = true;
	else
		scene->grid = false;
}
void MainWindow::numbering()
{
	scene->setMode(Scene::Mode(4));
}
void MainWindow::filtering()
{
	scene->filtering();
}
void MainWindow::unfiltering()
{
	scene->unfiltering();
}
void MainWindow::reverse()
{
	Edge *edge = selectedEdge();
	edge->reverse();
}	
void MainWindow::bringToFront()
{
	Edge *edge = selectedEdge();
	edge->setZValue(+1000.0);
}
void MainWindow::sendToBack()
{
	Edge *edge = selectedEdge();
	edge->setZValue(-1000.0);
}

void MainWindow::documentWasModified()
 {
     setWindowModified(SBMLText->document()->isModified());
	 setWindowModified(MIMMLText->document()->isModified());
 }
void MainWindow::sceneScaleChanged(const QString &scale)
 {
     double newScale = scale.left(scale.indexOf(tr("%"))).toDouble() / 100.0;
     QMatrix oldMatrix = view->matrix();
     view->resetMatrix();
     view->translate(oldMatrix.dx(), oldMatrix.dy());
     view->scale(newScale, newScale);
 }
void MainWindow::saveSBML()
{
	QString fileName = QFileDialog::getSaveFileName( this, tr("Save As"), "untitled",  tr("XML file (*.xml)"));
	scene->saveToSBML(fileName);
}
//void MainWindow::generateAutoLayout()
//{
//	scene->generateToAutoLayout();
//}
void MainWindow::addRightBranching()
{
	scene->addBranch(true);
}
void MainWindow::addLeftBranching()
{
	scene->addBranch(false);
}
void MainWindow::selectAll()
{
	scene->clearSelection();
	QPainterPath path(QPointF(0,0));
	path.lineTo(QPointF(0,2000));
	path.lineTo(QPointF(2000,2000));
	path.lineTo(QPointF(2000,0));
	path.lineTo(QPointF(0,0));
	scene->setSelectionArea(path);
}